<?php

namespace partner\functions\wechat\lib;


use partner\functions\wechat\lib\BaseWechatPartner;
use Exception;
use partner\functions\wechat\lib\BankAccountInfo\AccountCertInfo;

class BankAccountInfo extends BaseWechatPartner
{
    protected $desensitization_properties = [
        'account_name', 'account_number'
    ];

    private $directly_banks = [];

    private $is_directly_bank = false;

    // 账户类型
    public $bank_account_type;

    // 允许的账户类型
    private $allowed_bank_account_type = [
        // 1、若主体为企业/政府机关/事业单位/社会组织，可填写：对公银行账户。
        // 2、若主体为个体户，可选择填写：对公银行账户或经营者个人银行卡。
        // 对公银行账户
        'BANK_ACCOUNT_TYPE_CORPORATE', 
        // 经营者个人银行卡
        'BANK_ACCOUNT_TYPE_PERSONAL'
    ];

    // 开户名称(提醒：必须在HTTP头中上送Wechatpay-Serial, 该字段需进行加密处理，加密方法详见: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/wechatpay/wechatpay4_3.shtml)
    public $account_name = '';

    // 开户银行(17家直连银行参考: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/terms_definition/chapter1_1_3.shtml#part-4)
    // 非直连银行写“其他银行”
    public $account_bank = '其他银行';

    // 开户银行省市编码 (至少精确到市，参考《省市区编号对照表.xlsx》)
    public $bank_address_code = '';

    // 开户银行联行号 (17家直连银行无需填写, 如为其他银行，则开户银行全称（含支行）和开户银行联行号二选一。)
    public $bank_branch_id = '';

    // 开户银行全称（含支行）参考《开户银行全称(含支行)对照表.xlsx》
    public $bank_name = '';

    // 银行账号(提醒：必须在HTTP头中上送Wechatpay-Serial, 该字段需进行加密处理，加密方法详见: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/wechatpay/wechatpay4_3.shtml)
    public $account_number = '';

    // 银行账户证明材料
    // 1. 当主体类型是“政府机关/事业单位”时或所属行业为“党费”时，支持在有合法资金管理关系的情况下结算账户设置为非同名。
    // 2. 若结算账户设置为非同名，则需填写非同名证明材料，若结算账户为同名，则无需填写。
    public $account_cert_info;

    public function __construct($params = [], $rsa)
    {
        parent::__construct($params, $rsa);  
        
        $this->chkBankNameAndBranchId();
    }

    /**
     * 检查是开户银行全称（含支行）或开户银行联行号
     */
    public function chkBankNameAndBranchId()
    {
        if ($this->is_directly_bank === false && empty($this->bank_branch_id) && 
            empty($this->bank_name)) 
            throw new Exception('非直连银行必须填写开户银行全称（含支行）或开户银行联行号');

        return true;
    }

    public function getDirectlyBanks()
    {
        $banks = file_get_contents(realpath(dirname(__FILE__)) . '/../doc/banks.json');
        $this->directly_banks = json_decode($banks, true);
        return $this;
    }

    public function setBankAccountType(string $bank_account_type = '')
    {
        if (empty($bank_account_type))
            throw new Exception('账户类型不能为空');

        if (! in_array($bank_account_type, $this->allowed_bank_account_type))
            throw new Exception('非法账户类型');
        
        $this->bank_account_type = $bank_account_type;
        return $this;
    }

    public function setAccountName(string $account_name = '')
    {
        if (empty($account_name))
            throw new Exception('开户名称不能为空');
        $this->account_name = $account_name;
        return $this;
    }

    public function setAccountBank(string $account_bank = '')
    {
        if (empty($account_bank))
            throw new Exception('开户银行不能为空');

        if (empty($this->directly_banks))
            $this->getDirectlyBanks();
        $banks_name_arr = [];
        foreach($this->directly_banks as $banks_info) {
            array_push($banks_name_arr, $banks_info['bank_name']);
        }

        // account_bank是直连银行
        if (in_array($account_bank, $banks_name_arr)) {
            $this->account_bank = $account_bank;
            $this->is_directly_bank = true;
        }
        return $this;
    }

    public function setBankAddressCode(string $bank_address_code = '')
    {
        if (empty($bank_address_code))
            throw new Exception('开户银行省市编码不能为空');
        $this->bank_address_code = $bank_address_code;
        return $this;
    }

    public function setBankBranchId(string $bank_branch_id = '')
    {
        if ($this->account_bank)
            $this->bank_branch_id = $bank_branch_id;
        return $this;
    }

    public function setBankName(string $bank_name = '')
    {
        $this->bank_name = $bank_name;
        return $this;
    }

    public function setAccountNumber(string $account_number = '')
    {
        if (empty($account_number))
            throw new Exception('银行账号不能为空');
        // 银行账号 加密处理
        // $account_number = Utils::getEncrypt('/path/to/public_key.pem', $account_number);
        $this->account_number = $account_number;
        return $this;        
    }

    public function setAccountCertInfo(AccountCertInfo $account_cert_info) {
        $this->account_cert_info = $account_cert_info;
        return $this;
    }

    public function getAllowedBankAccountType()
    {
        return $this->allowed_bank_account_type;
    }

}